<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use think\Loader;
use app\admin\model\ShareStrategy;
use app\admin\model\StrategyTransaction;
/**
 * 策略管理
 *
 * @icon fa fa-circle-o
 */
class Strategy extends Backend
{
    /**
     * 快速搜索时执行查找的字段
     */
    protected $searchFields = 'all_no,id,user.mobile';
    
    /**
     * Strategy模型对象
     * @var \app\common\model\Strategy
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\ShareStrategy();
        $this->view->assign("statusList", $this->model->getStatusList());
        $this->view->assign("isAutoList", $this->model->getIsAutoList());
        $this->view->assign("payTypeList", $this->model->getPayTypeList());
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        
        if ($this->request->isAjax()) {
    
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            if (!empty($this->model) && $this->relationSearch) {
                $name = $this->model->getTable();
                $alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
                $aliasName = $alias[$name] . '.';
            }
            // 处理请求条件
           
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            //dump($where);exit;
        
            $query = $this->model
                ->with(['user'])
                ->where($where)
                ->order($sort, $order);
           
            $list = $query ->paginate($limit)->toArray();

            $newDataList = [];
            foreach($list['data'] as  $key => $row){
                
                $tempArr = $row;

                $tempArr['buy_time'] = $row['createtime'];
                $tempArr['no'] = preg_match('/\d+/',$row['all_no'],$arr)?$arr[0]:$row['all_no'];

                $price = getStockInfo($row['all_no']);
                $tempArr['earnest_money'] = $row['total_earnest'];

                if( $row['status'] == '1' ){
                    $tempArr['buy_price'] = round(floatval($row['total_earnest'])/floatval($row['total_lever_num'])*10,2);
                    $tempArr['income'] = round(floatval($price[$row['all_no']]['price']-$tempArr['buy_price'])*$row['total_lever_num'],2);
                    $tempArr['income_ratio'] = round(($price[$row['all_no']]['price']- $tempArr['buy_price'])/$tempArr['buy_price'],2);
                    $tempArr['pay_time'] = '';
                    $tempArr['sell_price'] = '-';
                    $tempArr['lever_num'] = $row['total_lever_num'];
                    $tempArr['num'] = $row['total_lever_num']/10;
                    
                    if( $this->isStatus3 ){
                        $tempArr['status'] = '3';
                        //if($tempArr['income_ratio'] > -0.7) continue;
                    }
                   
                }else if( $row['status'] == '0'){
                    $arr = StrategyTransaction::where(['strategy_id'=> $row['id']])->select();
                    $payMoney = 0; 
                    $pay_time = 0;
                    $lever_num = 0;
                    $buyMoney = 0;
                    foreach ($arr as $k => $value){
                        if($value['type'] == 'reduce' || $value['type'] == 'autoReduce'){
                            $payMoney += $value['pay_price']*$value['lever_num'];
                            $pay_time = $value['pay_time'] > $pay_time ? $value['pay_time'] : $pay_time;
                            $lever_num += $value['lever_num'];
                        }else{
                            $buyMoney += $value['buy_price']*$value['lever_num'];
                            $lever_num += $value['lever_num'];
                        }
                    }
                    $payPrice = $payMoney/intval($lever_num);
                    $buyPrice = $buyMoney/intval($lever_num);

                    $tempArr['lever_num'] = $lever_num;
                    $tempArr['num'] = $lever_num/10;

                    $tempArr['buy_time'] = $row['createtime'];
                    $tempArr['no'] = preg_match('/\d+/',$row['all_no'],$arr)?$arr[0]:$row['all_no'];
                    $tempArr['income'] = round(($payMoney/$lever_num-$buyMoney/$lever_num)*$lever_num,2);
                    $tempArr['income_ratio'] = round(($payPrice- $buyPrice)/$buyPrice,2);

                    $tempArr['sell_price'] = round($payPrice,2);
                    $tempArr['pay_time'] = $pay_time;
                    $tempArr['buy_price'] = round($buyPrice,2);
                    $tempArr['earnest_money'] = round($buyMoney/10,2);
                    
                }
                
                $newDataList[$key] = $tempArr;
            }

            $result = array("total" => $list['total'], "rows" => $newDataList);

            return json($result);
       }
        return $this->view->fetch();
    }

    protected $isStatus3 = false;

    /**
     * 获取指定策略的平仓总数
     */
    protected function getTotalCloseByTransaction($sid)
    {
        $model = new StrategyTransaction();
        $where = [];
        $where['strategy_id'] = $sid;
        $where['type'] = ['in',['reduce','autoReduce']];
        $total = $model->where($where)->sum('lever_num');
        //var_dump($sid,$total);exit;
        return intval($total);
    }

    /**
     * 生成查询所需要的条件,排序方式
     * @param mixed   $searchfields   快速查询的字段
     * @param boolean $relationSearch 是否关联查询
     * @return array
     */
    protected function buildparams($searchfields = null, $relationSearch = null)
    {
        $searchfields = is_null($searchfields) ? $this->searchFields : $searchfields;
        $relationSearch = is_null($relationSearch) ? $this->relationSearch : $relationSearch;
        $search = $this->request->get("search", '');
        $filter = $this->request->get("filter", '');
        $op = $this->request->get("op", '', 'trim');
        $sort = $this->request->get("sort", !empty($this->model) && $this->model->getPk() ? $this->model->getPk() : 'id');
        $order = $this->request->get("order", "DESC");
        $offset = $this->request->get("offset/d", 0);
        $limit = $this->request->get("limit/d", 999999);
        //新增自动计算页码
        $page = $limit ? intval($offset / $limit) + 1 : 1;
        if ($this->request->has("page")) {
            $page = $this->request->get("page/d", 1);
        }
        $this->request->get([config('paginate.var_page') => $page]);
        $filter = (array)json_decode($filter, true);
        $op = (array)json_decode($op, true);
        $filter = $filter ? $filter : [];

        $where = [];
        $alias = [];
        $bind = [];
        $name = '';
        $aliasName = '';
        if (!empty($this->model) && $this->relationSearch) {
            $name = $this->model->getTable();
            $alias[$name] = Loader::parseName(basename(str_replace('\\', '/', get_class($this->model))));
            $aliasName = $alias[$name] . '.';
        }
        $sortArr = explode(',', $sort);
        foreach ($sortArr as $index => & $item) {
            $item = stripos($item, ".") === false ? $aliasName . trim($item) : $item;
        }
        unset($item);
        $sort = implode(',', $sortArr);
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $where[] = [$aliasName . $this->dataLimitField, 'in', $adminIds];
        }
        if ($search) {
            $searcharr = is_array($searchfields) ? $searchfields : explode(',', $searchfields);
            foreach ($searcharr as $k => &$v) {
                $v = stripos($v, ".") === false ? $aliasName . $v : $v;
            }
            unset($v);
            $where[] = [implode("|", $searcharr), "LIKE", "%{$search}%"];
        }
        // 根据选项卡筛选数据
        $type = $this->request->get("type", 'all');
        $field = "{$aliasName}status";

        if( $type == '1' ){  // 持有
            $where[] = [$field,'=','1'];
        }elseif( $type == '0' ){   // 平仓
            $where[] = [$field,'=','0'];
        }elseif($type == '3'){  // 亏损预警增加查询条件
            $where[] = [$field,'=','1'];
            $this->isStatus3 = true;
        }
        $index = 0;
        foreach ($filter as $k => $v) {
            if (!preg_match('/^[a-zA-Z0-9_\-\.]+$/', $k)) {
                continue;
            }
            $sym = isset($op[$k]) ? $op[$k] : '=';
            if (stripos($k, ".") === false) {
                $k = $aliasName . $k;
            }
            $v = !is_array($v) ? trim($v) : $v;
            $sym = strtoupper(isset($op[$k]) ? $op[$k] : $sym);
            //null和空字符串特殊处理
            if (!is_array($v)) {
                if (in_array(strtoupper($v), ['NULL', 'NOT NULL'])) {
                    $sym = strtoupper($v);
                }
                if (in_array($v, ['""', "''"])) {
                    $v = '';
                    $sym = '=';
                }
            }

            switch ($sym) {
                case '=':
                case '<>':
                    $where[] = [$k, $sym, (string)$v];
                    break;
                case 'LIKE':
                case 'NOT LIKE':
                case 'LIKE %...%':
                case 'NOT LIKE %...%':
                    $where[] = [$k, trim(str_replace('%...%', '', $sym)), "%{$v}%"];
                    break;
                case '>':
                case '>=':
                case '<':
                case '<=':
                    $where[] = [$k, $sym, intval($v)];
                    break;
                case 'FINDIN':
                case 'FINDINSET':
                case 'FIND_IN_SET':
                    $v = is_array($v) ? $v : explode(',', str_replace(' ', ',', $v));
                    $findArr = array_values($v);
                    foreach ($findArr as $idx => $item) {
                        $bindName = "item_" . $index . "_" . $idx;
                        $bind[$bindName] = $item;
                        $where[] = "FIND_IN_SET(:{$bindName}, `" . str_replace('.', '`.`', $k) . "`)";
                    }
                    break;
                case 'IN':
                case 'IN(...)':
                case 'NOT IN':
                case 'NOT IN(...)':
                    $where[] = [$k, str_replace('(...)', '', $sym), is_array($v) ? $v : explode(',', $v)];
                    break;
                case 'BETWEEN':
                case 'NOT BETWEEN':
                    $arr = array_slice(explode(',', $v), 0, 2);
                    if (stripos($v, ',') === false || !array_filter($arr, function ($v) {
                            return $v != '' && $v !== false && $v !== null;
                        })) {
                        continue 2;
                    }
                    //当出现一边为空时改变操作符
                    if ($arr[0] === '') {
                        $sym = $sym == 'BETWEEN' ? '<=' : '>';
                        $arr = $arr[1];
                    } elseif ($arr[1] === '') {
                        $sym = $sym == 'BETWEEN' ? '>=' : '<';
                        $arr = $arr[0];
                    }
                    $where[] = [$k, $sym, $arr];
                    break;
                case 'RANGE':
                case 'NOT RANGE':
                    $v = str_replace(' - ', ',', $v);
                    $arr = array_slice(explode(',', $v), 0, 2);
                    if (stripos($v, ',') === false || !array_filter($arr)) {
                        continue 2;
                    }
                    //当出现一边为空时改变操作符
                    if ($arr[0] === '') {
                        $sym = $sym == 'RANGE' ? '<=' : '>';
                        $arr = $arr[1];
                    } elseif ($arr[1] === '') {
                        $sym = $sym == 'RANGE' ? '>=' : '<';
                        $arr = $arr[0];
                    }
                    $tableArr = explode('.', $k);
                    if (count($tableArr) > 1 && $tableArr[0] != $name && !in_array($tableArr[0], $alias) && !empty($this->model)) {
                        //修复关联模型下时间无法搜索的BUG
                        $relation = Loader::parseName($tableArr[0], 1, false);
                        $alias[$this->model->$relation()->getTable()] = $tableArr[0];
                    }
                    $where[] = [$k, str_replace('RANGE', 'BETWEEN', $sym) . ' TIME', $arr];
                    break;
                case 'NULL':
                case 'IS NULL':
                case 'NOT NULL':
                case 'IS NOT NULL':
                    $where[] = [$k, strtolower(str_replace('IS ', '', $sym))];
                    break;
                default:
                    break;
            }
            $index++;
        }
        //dump($where);exit;
        if (!empty($this->model)) {
            $this->model->alias($alias);
        }
        $model = $this->model;
        $where = function ($query) use ($where, $alias, $bind, &$model) {
            if (!empty($model)) {
                $model->alias($alias);
                $model->bind($bind);
            }
            foreach ($where as $k => $v) {
                if (is_array($v)) {
                    call_user_func_array([$query, 'where'], $v);
                } else {
                    $query->where($v);
                }
            }
        };
        return [$where, $sort, $order, $offset, $limit, $page, $alias, $bind];
    }

    protected $noNeedRight=[
        'edit'
    ];

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $id = $this->request->param('ids');
        if(empty($id)){
            $this->error(__('请携带id'));
        }

        $row = $this->model->get($id);
        
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row->num = $row->total_lever_num/10;
        $row->lever_num = $row->total_lever_num;
        $row->no = preg_match('/\d+/',$row->all_no,$arr)?$arr[0]:$row->all_no;
        $row->buy_price = round($row->total_earnest/$row->num,2);
        $row->earnest_money = $row->total_earnest;
        $row->sell_price = '-';
        $row->pay_type = $row->status;
        $row->buy_time = $row->createtime;
        $price = getStockInfo($row->all_no);
        $row->income = round(($price[$row->all_no]['price']-$row->buy_price)*$row->total_lever_num,2);
        $row->income_ratio = round(($price[$row->all_no]['price']- $row->buy_price)/$row->buy_price,2);
        $row->pay_time = '-';
        if($row->status == 0){
            $arr = StrategyTransaction::where(['strategy_id'=> $row->id,'type'=>'reduce'])->select();
            $money = 0; 
            $pay_time = 0;
            foreach ($arr as $key => $value){
                $money += $value['pay_price']*$value['lever_num'];
                $pay_time = $value['pay_time'] > $pay_time ? $value['pay_time'] : $pay_time;
            }
            $row->sell_price = round($money/$row->total_lever_num,2);
            $row->pay_time = $pay_time;
        }
        
        
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
          
            if ($params) {
                $params = $this->preExcludeFields($params);
        
                $validate = new \app\common\validate\Strategy;
    
    
                if (!$validate->check($params)) {
                    $this->error(__($validate->getError()));
                }
                $StrategyTransaction = new \app\admin\model\StrategyTransaction;
                //$sharestrategy = new\app\admin\model\ShareStrategy;
                //交易表数据
                $arr = $StrategyTransaction -> where(['strategy_id'=> $row->id,'user_id'=>$row->user_id])->where('type','in','add,new')->select();
                $params['total_earnest'] = $params['num'] * $params['buy_price'];
                $params['createtime'] = strtotime($params['buy_time']);
                //修改后保证金差价
                $earnestDifference = $row->total_earnest-$params['total_earnest'];
                //修改前时间
                $startime = $row->createtime;
                //时间差
                $difftime = $params['createtime'] - $startime;
                //策略表修改内容
                $shareparams = $params;
                unset($shareparams['num']);
                unset($shareparams['buy_price']);
                unset($shareparams['buy_time']);
                unset($shareparams['user_id']);
                //交易表修改内容
                $transactionparams = $params;
                $transactionparams['strategy_id'] = $row->id;
                unset($transactionparams['num']);
                unset($transactionparams['buy_time']);
                //unset($transactionparams['user_id']);
    //dd($transactionparams);
                try {
                    //策略买价后保证金变更修改用户余额
                    $userInfo = \app\common\model\User::find(['id'=>$row->user_id]);
                    $before = $userInfo->money;
                    $after = bcadd($before,$earnestDifference,2);
                    $userInfo->money = $after;
                    $res2 = $userInfo->save();
                    
                    $result = $row->allowField(['createtime','total_earnest'])->save($shareparams);
                    $res1 = true;
                    foreach ($arr as $key => $val){
                        if($val['type'] == 'new'){
                            $arr[$key]['createtime'] = $transactionparams['createtime'];
                            $arr[$key]['buy_price'] = $transactionparams['buy_price'];//buy_price    update
                            $transactionUser = StrategyTransaction::find($arr[$key]['id']);
                      
                            //$res = $transactionUser->allowField(['createtime','buy_price'])->save($arr[$key]);
                            $res = $transactionUser->update(['createtime'=>$transactionparams['createtime'],
                                                             'buy_time'=>$transactionparams['createtime'],
                                                             'buy_price'=>$transactionparams['buy_price'],
                                                             'earnest'=>$transactionparams['total_earnest'],
                                                             'id'=>$arr[$key]['id']
                                                             ]);
                            //dd($res);  
                
                        }elseif($val['type'] == 'add'){
                            $val['createtime'] = $val['createtime']+$difftime;
                            $transactionUser = StrategyTransaction::find($arr[$key]['id']);
                            $res1 = $transactionUser->update(['createtime'=>$val['createtime'],
                                                              'buy_time'=>$val['createtime'],
                                                              'id'=>$arr[$key]['id'] ]);
                        }
                        
                    }
                    
                    if ($result !== false && $res !== false && $res1 !== false && $res2 !== false) {
                        $res = file_get_contents('http://h5.zt-intl.com/api/trade/jhrw');
                        //dd($res);
                        $this->success();
                    } else {
                        $this->error($row->getError());
                    }
                } catch (\think\exception\PDOException $e) {
                    $this->error($e->getMessage());
                } catch (\think\Exception $e) {
                    $this->error($e->getMessage());
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }
    
    protected function editMoneyLog ($userId,$price,$beforeTime,$afterTime)
    {
        $moneyLog = \app\common\model\MoneyLog::where(['user_id'=>$userId,'createtime'=>['egt'=>$beforeTime]])->select();
        //foreach ($moneyLog as ){}
    }
}
